/* 
GeoGebra - Dynamic Mathematics for Schools
Copyright Markus Hohenwarter and GeoGebra Inc.,  http://www.geogebra.org

This file is part of GeoGebra.

This program is free software; you can redistribute it and/or modify it 
under the terms of the GNU General Public License as published by 
the Free Software Foundation.

 */

package geogebra.gui;

import geogebra.Plain;
import geogebra.gui.view.algebra.InputPanel;
import geogebra.kernel.*;
import geogebra.main.Application;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.Border;

public class SliderDialog extends JDialog
    implements
      ActionListener,
      KeyListener,
      WindowListener {

  /**
	 * 
	 */
  private static final long serialVersionUID = 1L;
  private JButton btApply, btCancel;
  private JRadioButton rbNumber, rbAngle;
  private InputPanel tfLabel;
  private JPanel optionPane;

  private final Application app;
  private SliderPanel sliderPanel;

  private GeoElement geoResult;
  private final GeoNumeric number;
  private final GeoAngle angle;

  /**
   * Creates a dialog to create a new GeoNumeric for a slider.
   * 
   * @param x
   *          , y: location of slider in screen coords
   */
  public SliderDialog(Application app, int x, int y) {
    super(app.getFrame(), true);
    this.app = app;
    addWindowListener(this);

    // create temp geos that may be returned as result
    Construction cons = app.getKernel().getConstruction();
    number = new GeoNumeric(cons);
    number.setEuclidianVisible(true);
    number.setSliderLocation(x, y);
    number.setAbsoluteScreenLocActive(true);
    number.setValue(1);

    angle = new GeoAngle(cons);
    angle.setEuclidianVisible(true);
    angle.setLabelMode(GeoElement.LABEL_NAME_VALUE);
    angle.setSliderLocation(x, y);
    angle.setAbsoluteScreenLocActive(true);
    angle.setValue(Math.PI / 180);

    geoResult = null;

    createGUI();
  }

  public void actionPerformed(ActionEvent e) {
    Object source = e.getSource();

    if (source == btApply) {
      geoResult = rbNumber.isSelected() ? number : angle;
      setVisible(false);
    } else if (source == btCancel)
      setVisible(false);
    else if (source == rbNumber || source == rbAngle) {
      GeoElement selGeo = rbNumber.isSelected() ? number : angle;
      GeoElement[] geos = {selGeo};
      sliderPanel.update(geos);

      // update label text field
      tfLabel.setText(selGeo.getDefaultLabel());
      setLabelFieldFocus();
    }
  }

  private void createGUI() {
    setTitle(Plain.Slider);
    setResizable(false);

    // Create components to be displayed

    // radio buttons for number or angle
    ButtonGroup bg = new ButtonGroup();
    rbNumber = new JRadioButton(Plain.Numeric);
    rbAngle = new JRadioButton(Plain.Angle);
    rbNumber.addActionListener(this);
    rbAngle.addActionListener(this);
    bg.add(rbNumber);
    bg.add(rbAngle);
    rbNumber.setSelected(true);
    // JPanel radioPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5));
    JPanel radioPanel = new JPanel();
    radioPanel.setLayout(new BoxLayout(radioPanel, BoxLayout.Y_AXIS));
    radioPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 20));
    radioPanel.add(rbNumber);
    radioPanel.add(rbAngle);

    // label textfield
    tfLabel = new InputPanel(number.getDefaultLabel(), app, 1, 10, false, true,
        false);
    tfLabel.getTextComponent().addKeyListener(this);
    Border border = BorderFactory.createCompoundBorder(BorderFactory
        .createTitledBorder(Plain.Name), BorderFactory.createEmptyBorder(5, 5,
        5, 5));
    tfLabel.setBorder(border);

    // put together label textfield and radioPanel
    JPanel topPanel = new JPanel();
    topPanel.setLayout(new BorderLayout(0, 0));
    topPanel.add(tfLabel, BorderLayout.CENTER);
    topPanel.add(radioPanel, BorderLayout.WEST);

    // slider panels
    sliderPanel = new SliderPanel(app, null, true);
    JPanel slPanel = new JPanel(new BorderLayout(0, 0));
    GeoElement[] geos = {number};
    slPanel.add(sliderPanel.update(geos), BorderLayout.CENTER);

    // buttons
    btApply = new JButton(Plain.Apply);
    btApply.setActionCommand("Apply");
    btApply.addActionListener(this);
    btCancel = new JButton(Plain.Cancel);
    btCancel.setActionCommand("Cancel");
    btCancel.addActionListener(this);
    JPanel btPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
    btPanel.add(btApply);
    btPanel.add(btCancel);

    // Create the JOptionPane.
    optionPane = new JPanel(new BorderLayout(5, 5));
    optionPane.add(topPanel, BorderLayout.NORTH);
    optionPane.add(slPanel, BorderLayout.CENTER);
    optionPane.add(btPanel, BorderLayout.SOUTH);
    optionPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

    // Make this dialog display it.
    setContentPane(optionPane);
    pack();
    setLocationRelativeTo(app.getFrame());
  }

  public GeoElement getResult() {
    if (geoResult != null) {
      // set label of geoResult
      String strLabel;
      try {
        strLabel = app.getKernel().getAlgebraProcessor().parseLabel(
            tfLabel.getText());
      } catch (Exception e) {
        strLabel = null;
      }
      geoResult.setLabel(strLabel);
    }

    return geoResult;
  }

  public void keyPressed(KeyEvent e) {
    switch (e.getKeyCode()) {
      case KeyEvent.VK_ENTER :
        btApply.doClick();
        break;

      case KeyEvent.VK_ESCAPE :
        btCancel.doClick();
        e.consume();
        break;
    }
  }

  public void keyReleased(KeyEvent arg0) {
  }

  public void keyTyped(KeyEvent arg0) {
  }

  private void setLabelFieldFocus() {
    tfLabel.getTextComponent().requestFocus();
    tfLabel.selectText();
  }

  public void windowActivated(WindowEvent arg0) {
  }

  public void windowClosed(WindowEvent arg0) {
  }

  public void windowClosing(WindowEvent arg0) {
  }

  public void windowDeactivated(WindowEvent arg0) {
  }

  public void windowDeiconified(WindowEvent arg0) {
  }

  public void windowIconified(WindowEvent arg0) {
  }

  public void windowOpened(WindowEvent arg0) {
    setLabelFieldFocus();
  }

}